#ifndef __APP_KEYPAGE__
#define __APP_KEYPAGE__
#include "typedef.h"

#if CONFIG_APP_KEYPAGE
#define  DOUBLE_KEY_DELAY_TIME      50
#define  REPROT_CONSUMER_LEN       (1+3) //音量加减
//report_id + data
#define  REPROT_INFO_LEN0         (1+3)
#define  REPROT_INFO_LEN1         (1+8)
#define  MOUSE_STEP                16//8
#define  COORDINATE_VM_HEAD_TAG   (0x4000)

typedef enum {
    KEY_UP = 0,
    KEY_DOWN,
    KEY_LEFT,
    KEY_RIGHT,
    KEY_PP_PRESS,
    KEY_ONE_PRESS
} key_op;

typedef struct {
    u16  x_vm_lab;
    u16  y_vm_lab;
    u8   head_tag;
} hid_vm_lab;

typedef struct {
    uint16_t x_lab;
    uint16_t y_lab;
    uint16_t x_lab_low;
    uint16_t x_lab_hig;
    uint16_t y_lab_low;
    uint16_t y_lab_hig;
} LabCoordinates;

enum {
    VM_RAED = 0,
    VM_WRITE
};

//----------------------------------
static const u8 keypage_report_map[] = {
    0x05, 0x0C,        // Usage Page (Consumer)
    0x09, 0x01,        // Usage (Consumer Control)
    0xA1, 0x01,        // Collection (Application)
    0x85, 0x03,        //   Report ID (3)
    0x15, 0x00,        //   Logical Minimum (0)
    0x25, 0x01,        //   Logical Maximum (1)
    0x75, 0x01,        //   Report Size (1)
    0x95, 0x0B,        //   Report Count (11)
    0x09, 0xEA,        //   Usage (Volume Decrement)
    0x09, 0xE9,        //   Usage (Volume Increment)
    0x0A, 0xAE, 0x01,  //   Usage (AL Keyboard Layout)
    0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x95, 0x01,        //   Report Count (1)
    0x75, 0x0D,        //   Report Size (13)
    0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0xC0,              // End Collection
    0x05, 0x0D,        // Usage Page (Digitizer)
    0x09, 0x02,        // Usage (Pen)
    0xA1, 0x01,        // Collection (Application)
    0x85, 0x02,        //   Report ID (2)
    0x09, 0x22,        //   Usage (Finger)
    0xA1, 0x02,        //   Collection (Logical)
    0x09, 0x42,        //     Usage (Tip Switch)
    0x15, 0x00,        //     Logical Minimum (0)
    0x25, 0x01,        //     Logical Maximum (1)
    0x75, 0x01,        //     Report Size (1)
    0x95, 0x01,        //     Report Count (1)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x09, 0x32,        //     Usage (In Range)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x95, 0x06,        //     Report Count (6)
    0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x75, 0x08,        //     Report Size (8)
    0x09, 0x51,        //     Usage (0x51)
    0x95, 0x01,        //     Report Count (1)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
    0x26, 0xFF, 0x0F,  //     Logical Maximum (4095)
    0x75, 0x10,        //     Report Size (16)
    0x55, 0x0E,        //     Unit Exponent (-2)
    0x65, 0x33,        //     Unit (System: English Linear, Length: Inch)
    0x09, 0x30,        //     Usage (X)
    0x35, 0x00,        //     Physical Minimum (0)
    0x46, 0xB5, 0x04,  //     Physical Maximum (1205)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x46, 0x8A, 0x03,  //     Physical Maximum (906)
    0x09, 0x31,        //     Usage (Y)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0xC0,              //   End Collection
    0x05, 0x0D,        //   Usage Page (Digitizer)
    0x09, 0x54,        //   Usage (0x54)
    0x95, 0x01,        //   Report Count (1)
    0x75, 0x08,        //   Report Size (8)
    0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x85, 0x08,        //   Report ID (8)
    0x09, 0x55,        //   Usage (0x55)
    0x25, 0x05,        //   Logical Maximum (5)
    0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
    0xC0,              // End Collection

    // 119 bytes
};


static const u8 keypage_report_map_ios[] = {
    0x05, 0x0C,        // Usage Page (Consumer)
    0x09, 0x01,        // Usage (Consumer Control)
    0xA1, 0x01,        // Collection (Application)
    0x85, 0x03,        //   Report ID (3)
    0x15, 0x00,        //   Logical Minimum (0)
    0x25, 0x01,        //   Logical Maximum (1)
    0x75, 0x01,        //   Report Size (1)
    0x95, 0x0B,        //   Report Count (11)
    0x09, 0xEA,        //   Usage (Volume Decrement)
    0x09, 0xE9,        //   Usage (Volume Increment)
    0x0A, 0xAE, 0x01,  //   Usage (AL Keyboard Layout)
    0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x95, 0x01,        //   Report Count (1)
    0x75, 0x0D,        //   Report Size (13)
    0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0xC0,              // End Collection
    0x05, 0x0D,        // Usage Page (Digitizer)
    0x09, 0x02,        // Usage (Pen)
    0xA1, 0x01,        // Collection (Application)
    0x85, 0x02,        //   Report ID (2)
    0x09, 0x22,        //   Usage (Finger)
    0xA1, 0x02,        //   Collection (Logical)
    0x09, 0x42,        //     Usage (Tip Switch)
    0x15, 0x00,        //     Logical Minimum (0)
    0x25, 0x01,        //     Logical Maximum (1)
    0x75, 0x01,        //     Report Size (1)
    0x95, 0x01,        //     Report Count (1)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x09, 0x32,        //     Usage (In Range)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x95, 0x06,        //     Report Count (6)
    0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x75, 0x08,        //     Report Size (8)
    0x09, 0x51,        //     Usage (0x51)
    0x95, 0x01,        //     Report Count (1)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
    0x26, 0xFF, 0x0F,  //     Logical Maximum (4095)
    0x75, 0x10,        //     Report Size (16)
    0x55, 0x0E,        //     Unit Exponent (-2)
    0x65, 0x33,        //     Unit (System: English Linear, Length: Inch)
    0x09, 0x30,        //     Usage (X)
    0x35, 0x00,        //     Physical Minimum (0)
    0x46, 0xB5, 0x04,  //     Physical Maximum (1205)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x46, 0x8A, 0x03,  //     Physical Maximum (906)
    0x09, 0x31,        //     Usage (Y)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0xC0,              //   End Collection
    0x05, 0x0D,        //   Usage Page (Digitizer)
    0x09, 0x54,        //   Usage (0x54)
    0x95, 0x01,        //   Report Count (1)
    0x75, 0x08,        //   Report Size (8)
    0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x85, 0x08,        //   Report ID (8)
    0x09, 0x55,        //   Usage (0x55)
    0x25, 0x05,        //   Logical Maximum (5)
    0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
    0xC0,              // End Collection
    0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
    0x09, 0x02,        // Usage (Mouse)
    0xA1, 0x01,        // Collection (Application)
    0x85, 0x04,        //   Report ID (4)
    0x09, 0x01,        //   Usage (Pointer)
    0xA1, 0x00,        //   Collection (Physical)
    0x95, 0x05,        //     Report Count (5)
    0x75, 0x01,        //     Report Size (1)
    0x05, 0x09,        //     Usage Page (Button)
    0x19, 0x01,        //     Usage Minimum (0x01)
    0x29, 0x05,        //     Usage Maximum (0x05)
    0x15, 0x00,        //     Logical Minimum (0)
    0x25, 0x01,        //     Logical Maximum (1)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x95, 0x01,        //     Report Count (1)
    0x75, 0x03,        //     Report Size (3)
    0x81, 0x01,        //     Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x75, 0x08,        //     Report Size (8)
    0x95, 0x01,        //     Report Count (1)
    0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
    0x09, 0x38,        //     Usage (Wheel)
    0x15, 0x81,        //     Logical Minimum (-127)
    0x25, 0x7F,        //     Logical Maximum (127)
    0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
    0x05, 0x0C,        //     Usage Page (Consumer)
    0x0A, 0x38, 0x02,  //     Usage (AC Pan)
    0x95, 0x01,        //     Report Count (1)
    0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
    0xC0,              //   End Collection
    0x85, 0x05,        //   Report ID (5)
    0x09, 0x01,        //   Usage (Consumer Control)
    0xA1, 0x00,        //   Collection (Physical)
    0x75, 0x0C,        //     Report Size (12)
    0x95, 0x02,        //     Report Count (2)
    0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
    0x09, 0x30,        //     Usage (X)
    0x09, 0x31,        //     Usage (Y)
    0x16, 0x01, 0xF8,  //     Logical Minimum (-2047)
    0x26, 0xFF, 0x07,  //     Logical Maximum (2047)
    0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
    0xC0,              //   End Collection
    0xC0,              // End Collection

    // 203 bytes
};

static const u8 key_vol_add[][REPROT_CONSUMER_LEN] = {
    {3, 0x02, 0x00, 0x00 },
    {3, 0x00, 0x00, 0x00 },
};
static const u8 key_vol_dec[][REPROT_CONSUMER_LEN] = {
    {3, 0x01, 0x00, 0x00 },
    {3, 0x00, 0x00, 0x00 },
};

//------------------------------------------------------
static const u8 key_idle_ios_0[][REPROT_INFO_LEN0] = {
    //松手
    {5, 0x00, 0xE0, 0xFF },
    {4, 0x00, 0x00, 0x00 },
};
static const u8 key_idle_ios_1[][REPROT_INFO_LEN0] = {
    //松手
    {5, 0x00, 0x10, 0x00 },
    {4, 0x00, 0x00, 0x00 },
};

//连接复位坐标
static const u8 key_connect_before[][REPROT_INFO_LEN0] = {
    {4, 0x00, 0x00, 0x00 },
    {4, 0x00, 0x00, 0x00 },
    /* {5, 0x01, 0xF8, 0x7F }, //左下*/
    /* {5, 0xFF, 0x17, 0x80 }, //右上 */
    {5, 0x01, 0x18, 0x80 }, //左上
    {5, 0x01, 0x18, 0x80 }, //左上
    {5, 0x01, 0x18, 0x80 }, //左上
    //复位坐标点，发松手坐标

    {5, 0x30, 0x00, 0x00 },
    {5, 0x30, 0x00, 0x00 },
    {5, 0x30, 0x00, 0x00 },

    {5, 0x00, 0x00, 0x04 },
    {5, 0x00, 0x00, 0x04 },
    {5, 0x00, 0x00, 0x04 },

    {4, 0x00, 0x00, 0x00 },
};

//上键（短按）
static const u8 key_up_before[][REPROT_INFO_LEN0] = {//上一个
    {4, 0x01, 0x00, 0x00 },
    {5, 0x00, 0x00, 0x02 },
    {5, 0x00, 0x00, 0x03 },
    {4, 0x00, 0x00, 0x00 },

    {5, 0x00, 0x00, 0xFE },
    {5, 0x00, 0x00, 0xFD },
    {4, 0x00, 0x00, 0x00 },
};

//Report ID (2)
static const u8 key_up_click[][REPROT_INFO_LEN1] = {
    {2, 0x07, 0x06, 0x70, 0x07, 0xf4, 0x03, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0x4c, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0x78, 0x05, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0xa4, 0x06, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0xd0, 0x07, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0xfc, 0x08, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0x28, 0x0a, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0x54, 0x0b, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0x80, 0x0c, 0x01, 0x00 },
    {2, 0x00, 0x06, 0x70, 0x07, 0xac, 0x0d, 0x00, 0x00 },
};

//上键（HOLD） 收到按键HOLD消息发1次，
//Report ID (3)
static const u8 key_up_hold_press[][REPROT_INFO_LEN0] = {
    {3, 0x02, 0x00, 0x00 },
};
static const u8 key_up_hold_release[][REPROT_INFO_LEN0] = {
    {3, 0x00, 0x00, 0x00 },
};

//------------------------------------------------------
//下键（短按）
static const u8 key_down_before[][REPROT_INFO_LEN0] = {//下一个
    {4, 0x01, 0x00, 0x00 },
    {5, 0x00, 0x00, 0xFE },
    {5, 0x00, 0x00, 0xFD },
    {4, 0x00, 0x00, 0x00 },

    {5, 0x00, 0x00, 0x02 },
    {5, 0x00, 0x00, 0x03 },
    {4, 0x00, 0x00, 0x00 },
};

static const u8 key_down_click[][REPROT_INFO_LEN1] = {
    //Report ID (2)
    {2, 0x07, 0x06, 0x70, 0x07, 0x80, 0x0c, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0x28, 0x0a, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0xfc, 0x08, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0xd0, 0x07, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0xa4, 0x06, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0x78, 0x05, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0x4c, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0x20, 0x03, 0x01, 0x00 },
    {2, 0x07, 0x06, 0x70, 0x07, 0xf4, 0x01, 0x01, 0x00 },
    {2, 0x00, 0x06, 0x70, 0x07, 0xc8, 0x00, 0x00, 0x00 },
};

//下键（HOLD） 收到按键HOLD消息发1次
//Report ID (3)
static const u8 key_down_hold_press[][REPROT_INFO_LEN0] = {
    {3, 0x01, 0x00, 0x00 },
};

static const u8 key_down_hold_release[][REPROT_INFO_LEN0] = {
    {3, 0x00, 0x00, 0x00 }
};

//---------------------------------------------------------
//左键（短按）
static const u8 key_left_before[][REPROT_INFO_LEN0] = { //左滑
    {4, 0x01, 0x00, 0x00 },
    {5, 0x20, 0x00, 0x00 },
    {5, 0x20, 0x00, 0x00 },
    {4, 0x00, 0x00, 0x00 },

    {5, 0xE0, 0x0F, 0x00 },
    {5, 0xE0, 0x0F, 0x00 },
    {4, 0x00, 0x00, 0x00 },
};

static const u8 key_left_click[][REPROT_INFO_LEN1] = {
    //Report ID (2)
    {2, 0x07, 0x04, 0x00, 0x02, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x04, 0x8a, 0x02, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x04, 0xb4, 0x03, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x04, 0xe2, 0x04, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x04, 0x0e, 0x06, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x04, 0x3a, 0x07, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x04, 0x66, 0x08, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x04, 0x92, 0x09, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x04, 0xbe, 0x0a, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x04, 0xea, 0x0b, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x00, 0x04, 0x16, 0x0d, 0x70, 0x04, 0x00, 0x00 },
};

//---------------------------------------------------------
//右键（短按）
static const u8 key_right_before[][REPROT_INFO_LEN0] = {//右滑
    {4, 0x01, 0x00, 0x00 },
    {5, 0xE0, 0x0F, 0x00 },
    {5, 0xE0, 0x0F, 0x00 },
    {4, 0x00, 0x00, 0x00 },

    {5, 0x20, 0x00, 0x00 },
    {5, 0x20, 0x00, 0x00 },
    {4, 0x00, 0x00, 0x00 },
};

static const u8 key_right_click[][REPROT_INFO_LEN1] = {
    //Report ID (2)
    {2, 0x07, 0x05, 0x00, 0x0d, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x05, 0x48, 0x0d, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x05, 0x1c, 0x0c, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x05, 0xf0, 0x0a, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x05, 0xc4, 0x09, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x05, 0x98, 0x08, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x05, 0x6c, 0x07, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x05, 0x40, 0x06, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x05, 0x14, 0x05, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x07, 0x05, 0xe8, 0x03, 0x70, 0x04, 0x01, 0x00 },
    {2, 0x00, 0x05, 0xbc, 0x02, 0x70, 0x04, 0x00, 0x00 },
};

//---------------------------------------------------------
//中键（短按，长按）
//-------按下-------
static  u8 key_pp_press[][REPROT_INFO_LEN1] = {
    //Report ID (2)
    {2, 0x07, 0x07, 0x70, 0x07, 0x70, 0x07, 0x01, 0x00 },
};

//-------松开-------
static u8 key_pp_release_before[][REPROT_INFO_LEN0] = {//点赞
    {4, 0x01, 0x00, 0x00 },
    {4, 0x00, 0x00, 0x00 },
};

static u8 key_pp_release[][REPROT_INFO_LEN1] = {
    //Report ID (2)
    {2, 0x00, 0x07, 0x70, 0x07, 0x70, 0x07, 0x00, 0x00  },
};

//双击相当于连续发两次
//HOLD动作 就是先发按下，等松手再发松开包

//---------------------------------------------------------
//单键（短按，长按）
//-------按下-------
static const u8 key_one_press_before[][REPROT_INFO_LEN0] = {//暂停
    {4, 0x01, 0x00, 0x00 },
};

static const u8 key_one_press[][REPROT_INFO_LEN1] = {
    //Report ID (2)
    {2, 0x07, 0x08, 0x00, 0x08, 0x60, 0x0d, 0x01, 0x00  },
};

//-------松开-------
static const u8 key_one_release_before[][REPROT_INFO_LEN0] = {
    //Report ID (4)
    {4, 0x00, 0x00, 0x00 },
};
static const u8 key_one_release[][REPROT_INFO_LEN1] = {
    //Report ID (2)
    {2, 0x00, 0x08, 0x00, 0x08, 0x60, 0x0d, 0x00, 0x00  },
};

static u8 key_focus_ios[][REPROT_INFO_LEN0] = {//相机移动焦点
    {4, 0x00, 0x00, 0x00 },
    {5, 0x00, 0x00, 0x00 },
};

//------
//双击相当于连续发两次
//HOLD动作 就是先发按下，等松手再发松开包
#endif

#endif
